home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / sml_nj / 93src.lha / src / sparc / sparcas.sml < prev    next >
Encoding:
Text File  |  1993-01-27  |  7.1 KB  |  218 lines

  1. (* sparcas.sml
  2.  *
  3.  * Copyright 1989 by AT&T Bell Laboratories
  4.  *
  5.  * The SPARC assembly code emitter.
  6.  *
  7.  * AUTHOR:  John Reppy
  8.  *        Cornell University
  9.  *        Ithaca, NY 14853
  10.  *        jhr@cs.cornell.edu
  11.  *)
  12.  
  13. structure SparcAsCode =
  14. struct
  15.     val outfile = ref(IO.std_out)
  16. end (* SparcAsCode *)
  17.  
  18.  
  19. structure SparcAsEmit : EMITTER =
  20. struct
  21.  
  22.     open SparcAsCode SparcInstr
  23.  
  24.   (** The location counter **)
  25.     val loc = ref 0
  26.     fun advance n = (loc := !loc + n)
  27.     fun advance4 () = (loc := !loc + 4)
  28.  
  29.   (** utility routines **)
  30.     local
  31.       val hexDigits = "0123456789abcdef"
  32.       fun f (0, l) = l
  33.     | f (n, l) = (
  34.         f (Bits.rshift(n, 4), chr(ordof(hexDigits, Bits.andb(n, 15))) :: l))
  35.       fun cvt 0 = ["0", "x", "0"]
  36.     | cvt n = ("0" :: "x" :: f(n, nil))
  37.     in
  38.     fun atoi i = implode(if (i < 0) then "-" :: cvt(~i) else cvt i)
  39.     end
  40.  
  41.     fun emit s = output (!outfile, s)
  42.  
  43.     fun newLine () = emit "\n"
  44.  
  45.     fun emitLabel (INFO{nameOf,...}) lab = emit(nameOf lab)
  46.  
  47.     fun emitOffset 0 = ()
  48.       | emitOffset i = (if (i < 0)
  49.       then (emit "-"; emit(atoi(~i)))
  50.       else (emit "+"; emit(atoi i)))
  51.  
  52.  
  53.     fun emitLong i = (emit "\t.long\t"; emit(atoi i); newLine(); advance4())
  54.  
  55.     local
  56.       fun oct i = let
  57.         val m = Integer.makestring
  58.         in
  59.           m(i quot 64)^m((i quot 8)mod 8)^m(i mod 8)
  60.         end
  61.       fun c_char "\n" = "\\n"
  62.     | c_char "\t" = "\\t"
  63.     | c_char "\\" = "\\\\"
  64.     | c_char "\"" = "\\\""
  65.     | c_char c = if ord c < 32 then "\\"^oct(ord c) else c
  66.       fun a_str s = implode(map c_char (explode s))
  67.     in
  68.     fun emitString s = (
  69.       emit "\t.ascii \""; emit(a_str s); emit "\"\n"; emit "\t.align\t4\n";
  70.       advance(size s))
  71.     end (* local *)
  72.  
  73.     exception BadReal of string
  74.     fun emitReal r = (emit "\t.double\t"; emit r; newLine(); advance 8)
  75.  
  76.     fun emitAddr (info as INFO{addrOf,...}) (lab, k) = (
  77.       emit "\t.long\t("; emitLabel info lab; emit "-.)"; emitOffset k;
  78.       emit "\t| "; emit(atoi(k + addrOf lab - !loc)); newLine();
  79.       advance4())
  80.  
  81.     fun define (info as INFO{addrOf,...}) lab = (
  82.                                
  83.          emitLabel info lab;  emit ":\t| .="; emit(atoi(!loc)); 
  84.          emit ", "; emit(atoi(addrOf lab)); newLine())
  85.  
  86.     local
  87.       open System.Tags
  88.     in
  89.     fun mark () = (
  90.       emit "\t.long\tMAKE_DESC(((.-L0)/4+1),tag_backptr)\t| ";
  91.       emit (atoi (make_desc((!loc + 4) quot 4, tag_backptr))); newLine();
  92.       advance4())
  93.     end (* local *)
  94.  
  95.    fun emitInstr info = let
  96.       val emitLabel = emitLabel info
  97.  
  98.       fun comma () = emit ","
  99.  
  100.       fun emitReg (REG i) = if (i < 16)
  101.         then if (i < 8)
  102.           then (emit "%g"; emit (makestring i))
  103.           else (emit "%o"; emit (makestring (i-8)))
  104.         else if (i < 24)
  105.           then (emit "%l"; emit (makestring (i-16)))
  106.           else (emit "%i"; emit (makestring (i-24)))
  107.  
  108.       fun emitFReg (FREG i) = (emit "%f"; emit (makestring i))
  109.  
  110.       fun emitCC CC_A = emit "a"
  111.     | emitCC CC_E = emit "e"     | emitCC CC_NE = emit "ne"
  112.     | emitCC CC_L = emit "l"     | emitCC CC_LE = emit "le"
  113.     | emitCC CC_G = emit "g"     | emitCC CC_GE = emit "ge"
  114.     | emitCC CC_LEU = emit "leu" | emitCC CC_GEU = emit "geu"
  115.  
  116.       fun emitLExp (LABELexp{base, dst, offset=0}) = (
  117.         emitLabel dst; emit "-"; emitLabel base)
  118.     | emitLExp (LABELexp{base, dst, offset}) = (
  119.         emit "("; emitLabel dst; emitOffset offset; emit ")-"; emitLabel base)
  120.  
  121.       fun emitRand (REGrand r) = emitReg r
  122.     | emitRand (IMrand i) = emit (atoi i)
  123.     | emitRand (LABrand lexp) = emitLExp lexp
  124.     | emitRand (LOrand lexp) = (emit "%lo("; emitLExp lexp; emit ")")
  125.     | emitRand (HIrand lexp) = (emit "%hi("; emitLExp lexp; emit ")")
  126.  
  127.       fun emitArgs (r1, arg, rd) = (
  128.         emitReg r1; comma(); emitRand arg; comma(); emitReg rd)
  129.  
  130.       fun emitAddr (r1, b) = (emitReg r1;
  131.         case b
  132.          of REGrand(REG 0) => ()
  133.           | REGrand r2 => (emit "+"; emitReg r2)
  134.           | IMrand i => emitOffset i
  135.           | LABrand l => (emit "+"; emitLExp l)
  136.           | LOrand l => (emit "+%lo("; emitLExp l; emit ")")
  137.           | _ => (ErrorMsg.impossible "[emitAddr]"))
  138.  
  139.       fun emitMemAddr args = (emit "["; emitAddr args; emit "]")
  140.  
  141.       fun emitFArgs3 (f1, f2, fd) = (
  142.         emitFReg f1; comma(); emitFReg f2; comma(); emitFReg fd)
  143.       fun emitFArgs2 (f1, f2) = (
  144.         emitFReg f1; comma(); emitFReg f2)
  145.     in
  146.  
  147.       fn I => (
  148.       emit "\t";
  149.       case I
  150.        of (I_nop) => emit "nop"
  151.         | (I_ld(a, b, c)) => (emit "ld "; emitMemAddr(a, b); comma(); emitReg c)
  152.         | (I_ldb(a, b, c)) => (emit "ldub "; emitMemAddr(a, b); comma(); emitReg c)
  153.         | (I_ldf(a, b, c)) => (emit "ldf "; emitMemAddr(a, b); comma(); emitFReg c)
  154.         | (I_st(a, b, c)) => (emit "st "; emitReg c; comma(); emitMemAddr(a, b))
  155.         | (I_stb(a, b, c)) => (emit "stb "; emitReg c; comma(); emitMemAddr(a, b))
  156.         | (I_stf(a, b, c)) => (emit "stf "; emitFReg c; comma(); emitMemAddr(a, b))
  157.         | (I_sethi(x, rd)) => (
  158.         emit "sethi ";
  159.         case x
  160.          of IMrand i => emit(atoi i)
  161.           | HIrand _ => emitRand x
  162.           | _ => ErrorMsg.impossible "[emitInstr.sethi]";
  163.         comma(); emitReg rd)
  164.         | (I_bcc(cc, l)) => (emit "b"; emitCC cc; emit " "; emitLabel l)
  165.         | (I_fbcc(cc, l)) => (emit "fb"; emitCC cc; emit " "; emitLabel l)
  166.         | (I_jmpl(a, b, REG 0)) => (emit "jmp "; emitAddr(a, b))
  167.         | (I_jmpl(a, b, rd)) => (emit "jmpl "; emitAddr(a, b); comma(); emitReg rd)
  168.         | (I_call2) => (emit "call .+8")
  169.         | (I_add args) => (emit "add "; emitArgs args)
  170.         | (I_addcc args) => (emit "addcc "; emitArgs args)
  171.         | (I_taddcctv args) => (emit "taddcctv "; emitArgs args)
  172.         | (I_sub args) => (emit "sub "; emitArgs args)
  173.         | (I_subcc(a, b, REG 0)) => (
  174.         emit "cmp "; emitReg a; comma();
  175.         case b
  176.          of REGrand r2 => emitReg r2
  177.           | IMrand i => emit(atoi i)
  178.           | _ => ErrorMsg.impossible "[emitInstr.addcc]")
  179.         | (I_subcc args) => (emit "subcc "; emitArgs args)
  180.         | (I_sll args) => (emit "sll "; emitArgs args)
  181.         | (I_sra args) => (emit "sra "; emitArgs args)
  182.         | (I_and args) => (emit "and "; emitArgs args)
  183.         | (I_andcc(a, b, REG 0)) => (
  184.         emit "btst "; emitReg a; comma();
  185.         case b
  186.          of REGrand r2 => emitReg r2
  187.           | IMrand i => emit(atoi i)
  188.           | _ => ErrorMsg.impossible "[emitInstr.andcc]")
  189.         | (I_andcc args) => (emit "andcc "; emitArgs args)
  190.         | (I_or(REG 0, arg, rd)) => (emit "mov "; emitRand arg; comma(); emitReg rd)
  191.         | (I_or args) => (emit "or "; emitArgs args)
  192.         | (I_xor args) => (emit "xor "; emitArgs args)
  193.         | (I_not(r1, rd)) => (emit "not "; emitReg r1; comma(); emitReg rd)
  194.         | (I_tvs) => emit "tvs ST_INT_OVERFLOW"
  195.         | (I_fadd args) => (emit "faddd "; emitFArgs3 args)
  196.         | (I_fsub args) => (emit "fsubd "; emitFArgs3 args)
  197.         | (I_fmul args) => (emit "fmuld "; emitFArgs3 args)
  198.         | (I_fdiv args) => (emit "fdivd "; emitFArgs3 args)
  199.         | (I_fneg args) => (emit "fneg "; emitFArgs2 args)
  200.         | (I_fabs args) => (emit "fabs "; emitFArgs2 args)
  201.         | (I_fcmp args) => (emit "fcmp "; emitFArgs2 args)
  202.         | (I_fmov args) => (emit "fmov "; emitFArgs2 args)
  203.         | (I_fitod args) => (emit "fitod "; emitFArgs2 args)
  204.       (* end of case *);
  205.       emit "\t| .="; emit(atoi(!loc));
  206.       newLine();
  207.       advance4())
  208.  
  209.     end (* local *)
  210.  
  211.     fun comment s = emit s
  212.  
  213.     fun init (n : int) = (
  214.       loc := 0;
  215.       emit "| code size = "; emit(makestring n); emit " bytes\n")
  216.  
  217. end (* structure SparcAsEmit *)
  218.